home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / tvtoys04.zip / NEWMOUSE.PAS < prev    next >
Pascal/Delphi Source File  |  1993-12-07  |  9KB  |  378 lines

  1. (***************************************************************************
  2.   NewMouse unit
  3.   Snap-in replacement mouse cursor intended for Turbo Vision.
  4.   PJB September 1, 1993, Internet mail to d91-pbr@nada.kth.se
  5.   Copyright 1993, All Rights Reserved
  6.   Free source, use at your own risk.
  7.   If modified, please state so if you pass this around.
  8.  
  9.   Use this unit and strange TEXT video modes will work with the mouse.
  10.   This unit does NOT replace a resident mouse driver.
  11.  
  12.   ■ Preferred usage:
  13.     Define UseNewMouse in TOYCFG if you use TToyApp.
  14.  
  15.   (only if you don't use TToyApp should you put NewMouse in your uses
  16.   list). For non TV operation, make sure you use this unit before any
  17.   mouse event handling code executes, i.e. you might have to put this
  18.   unit first in the first uses list.
  19.  
  20.   Use UseNewMouse to toggle operation on/off, default is on.
  21.   Don't switch video mode without hiding the mouse. Preferrably use
  22.   Turbo Vision code to switch modes.
  23.   To use graphics modes, first hide the mouse and then toggle NewMouse
  24.   off with UseNewMouse(False). Don't forget to turn it back on.
  25.   Don't shell to DOS without turning NewMouse off. TToyApp does this
  26.   for you if you define UseNewMouse.
  27.  
  28.   No hardware cursor support. You cannot change the appearance
  29.   of the mouse cursor without turning NewMouse off.
  30.  
  31.   You cannot overlay this unit.
  32.  
  33.   My Microsoft mouse driver v8.20 only works properly in 80x25, it
  34.   skips odd columns in ALL other text modes. This has been worked around
  35.   by using the virtual X coordinates passed to the event handler.
  36.  
  37. ***************************************************************************)
  38. unit NewMouse;
  39.  
  40. {$O-,R-,S-,X+}
  41. {$C FIXED PRELOAD PERMANENT}
  42.  
  43. interface
  44.  
  45.   uses
  46.     Dos,
  47.    {$IFDEF DPMI}
  48.     WinAPI,
  49.    {$ENDIF}
  50.     Drivers;
  51.  
  52.   procedure UseNewMouse(Yes:Boolean);
  53.  
  54.  
  55. (***************************************************************************
  56. ***************************************************************************)
  57. implementation
  58.  
  59.  
  60.   (*******************************************************************
  61.     Data segment variables
  62.   *******************************************************************)
  63.   const
  64.     CrtWidth      = $4A;
  65.  
  66.     OldPos        : Word = 1;
  67.     Visible       : Byte = $FF;
  68.     NewMouseInUse : Boolean = True;
  69.  
  70.   var
  71.     Attr   : Byte;
  72.     LastX  : Byte;
  73.     LastY  : Byte;
  74.  
  75.     VirtualLeft        : Word;
  76.     RecalcVirtualLeft  : Boolean;
  77.  
  78.     OldInt33           : Pointer;
  79.     InstalledMouseProc : Pointer;
  80.  
  81.  
  82.   (*******************************************************************
  83.     Called by original mouse driver with new mouse events
  84.     This code trashes DI, but TV doesn't mind
  85.   *******************************************************************)
  86.   procedure MouseProc; far; assembler;
  87.   asm
  88.       mov  di,SEG @Data
  89.       mov  ds,di
  90.  
  91.       cmp  NewMouseInUse,0              { Not in use, skip code }
  92.       je   @PosOK
  93.  
  94.       cmp  RecalcVirtualLeft,False      { DOS shell moved mouse? }
  95.       je   @NoRecalc
  96.       mov  RecalcVirtualLeft,False
  97.  
  98.       { Recalculate virtual left margin }
  99.       push si
  100.       sub  si,cx
  101.       mov  VirtualLeft,si
  102.       pop  si
  103.  
  104.       { Calculate an X coordinate from virtual X position data }
  105.     @NoRecalc:
  106.       xor  cx,cx
  107.       sub  si,VirtualLeft
  108.       js   @NewVirtualLeft               { Off left }
  109.  
  110.       mov  es,Seg0040
  111.       mov  di,es:[CrtWidth].Word
  112.       mov  cl,3
  113.       shl  di,cl
  114.       dec  di                            { Max X }
  115.  
  116.       mov  cx,si
  117.       sub  si,di
  118.       jbe  @PosOK
  119.       mov  cx,di                         { Off right }
  120.  
  121.     @NewVirtualLeft:
  122.       add  VirtualLeft,si                { Change left margin }
  123.  
  124.       { Call old mouse handler }
  125.     @PosOK:
  126.       push cx
  127.       push dx
  128.       call DWORD PTR InstalledMouseProc
  129.       pop  dx
  130.       pop  cx
  131.  
  132.       mov  ax,SEG @Data
  133.       mov  ds,ax
  134.  
  135.       cmp  NewMouseInUse,0           { Not in use, don't draw }
  136.       je   @Fin2
  137.  
  138.       { Calculate position }
  139.       mov  bx,cx
  140.       mov  cl,3
  141.       shr  bx,cl
  142.       shr  dx,cl
  143.  
  144.       mov  LastX,bl
  145.       mov  LastY,dl
  146.  
  147.       mov  es,Seg0040
  148.  
  149.       mov  al,es:[CrtWidth].Byte
  150.       mul  dl
  151.       add  bx,ax
  152.       shl  bx,1
  153.       inc  bx
  154.  
  155.       cli                       { Reentrancy problems on slow machines }
  156.  
  157.       test Visible,80h
  158.       je   @Show
  159.       mov  OldPos,bx
  160.       jmp  @Fin
  161.  
  162.       { Draw mouse cursor }
  163.     @Show:
  164.       mov  es,Drivers.ScreenBuffer+2.Word
  165.  
  166.       mov  di,OldPos
  167.       mov  al,Attr
  168.       mov  es:[di],al
  169.  
  170.       mov  OldPos,bx
  171.  
  172.       mov  al,es:[bx]
  173.       mov  Attr,al
  174.  
  175.       not  al
  176.       and  al,77h
  177.       mov  es:[bx],al
  178.  
  179.     @Fin:
  180.       sti
  181.  
  182.     @Fin2:
  183.   end;
  184.  
  185.  
  186.   (*******************************************************************
  187.     Snooping mouse INT 33 replacement routines
  188.   *******************************************************************)
  189.   procedure HideMouse; assembler;
  190.   asm
  191.       sub  Visible,1
  192.       jnc  @Fin
  193.  
  194.       mov  es,Drivers.ScreenBuffer+2.Word
  195.  
  196.       cli
  197.       mov  bx,OldPos
  198.       mov  al,Attr
  199.       mov  es:[bx],al
  200.       sti
  201.  
  202.     @Fin:
  203.   end;
  204.  
  205.   procedure ShowMouse; assembler;
  206.   asm
  207.       cli
  208.       inc  Visible
  209.       jne  @Fin
  210.  
  211.       mov  es,Seg0040
  212.       mov  al,es:[CrtWidth].Byte
  213.       mul  LastY
  214.  
  215.       mov  bl,LastX
  216.       mov  bh,0
  217.  
  218.       add  bx,ax
  219.       shl  bx,1
  220.       inc  bx
  221.       mov  OldPos,bx
  222.  
  223.       mov  es,Drivers.ScreenBuffer+2.Word
  224.  
  225.       mov  al,es:[bx]
  226.       mov  Attr,al
  227.       not  al
  228.       and  al,77h
  229.       mov  es:[bx],al
  230.  
  231.     @Fin:
  232.       sti
  233.   end;
  234.  
  235.   procedure InstallProc; assembler;
  236.   asm
  237.       mov  ax,es
  238.       or   ax,dx
  239.       je   @Nil
  240.  
  241.       mov  InstalledMouseProc.Word, dx
  242.       mov  InstalledMouseProc+2.Word, es
  243.  
  244.       push cs
  245.       pop  es
  246.       mov  dx,OFFSET MouseProc
  247.  
  248.     @Nil:
  249.       mov  ax,12
  250.       pushf
  251.       call DWORD PTR [OldInt33]
  252.   end;
  253.  
  254.  
  255.   (*******************************************************************
  256.     Mouse INT 33 snooping procedure
  257.     Looks for HideMouse, ShowMouse and InstallEventHandler
  258.   *******************************************************************)
  259.   procedure NewInt33; far; assembler;
  260.   asm
  261.       push ds
  262.       mov  ds,@DataSeg.Word
  263.  
  264.       cmp  NewMouseInUse,0
  265.       je   @Chain
  266.  
  267.       cmp  ax,1
  268.       je   @Local
  269.       cmp  ax,2
  270.       je   @Local
  271.       cmp  ax,12
  272.       je   @Local
  273.  
  274.     @Chain:
  275.       push ax                  { Dummy }
  276.  
  277.       push bp
  278.       mov  bp,sp
  279.       push [bp+4].Word         { Old DS }
  280.       push ax
  281.  
  282.       mov  ax,OldInt33.Word
  283.       mov  [bp+2],ax
  284.       mov  ax,OldInt33.Word+2
  285.       mov  [bp+4],ax
  286.  
  287.       pop  ax
  288.       pop  ds
  289.       pop  bp
  290.       retf                      { Chain to old int handler }
  291.  
  292.     @Local:
  293.       push ax
  294.       push bx
  295.       push dx
  296.       push es
  297.  
  298.       cmp  ax,2
  299.       je   @Hide
  300.       ja   @Inst
  301.       call ShowMouse
  302.       jmp  @Fin
  303.  
  304.     @Hide:
  305.       call HideMouse
  306.       jmp  @Fin
  307.  
  308.     @Inst:
  309.       call InstallProc
  310.  
  311.     @Fin:
  312.       pop  es
  313.       pop  dx
  314.       pop  bx
  315.       pop  ax
  316.       pop  ds
  317.       iret
  318.  
  319.     @DataSeg:
  320.       dw   SEG @Data
  321.   end;
  322.  
  323.  
  324.   (*******************************************************************
  325.     Toggle NewMouse operation on/off
  326.     Toggle off before you switch to graphics mode
  327.   *******************************************************************)
  328.   procedure UseNewMouse(Yes:Boolean);
  329.   begin
  330.     if ButtonCount<>0 then
  331.     begin
  332.       NewMouseInUse:=Yes;
  333.       RecalcVirtualLeft:=True;
  334.  
  335.     (*******************************************************************
  336.       Get last mouse position
  337.     *******************************************************************)
  338.       asm
  339.         mov  ax,3
  340.         int  33h                 { Mouse pos in CX/DX }
  341.  
  342.         mov  bx,cx
  343.         mov  cl,al
  344.         shr  bx,cl
  345.         shr  dx,cl
  346.         mov  LastX,bl
  347.         mov  LastY,dl
  348.       end;
  349.     end;
  350.   end;
  351.  
  352.  
  353.     (*******************************************************************
  354.       Make sure we remove our snooping hook
  355.     *******************************************************************)
  356.   var
  357.     SaveExit : Pointer;
  358.  
  359.   procedure ExitMouse; far;
  360.   begin
  361.     ExitProc:=SaveExit;
  362.     SetIntVec($33, OldInt33);
  363.   end;
  364.  
  365.  
  366. (***************************************************************************
  367.   Installation code
  368. ***************************************************************************)
  369.  
  370. begin
  371.   GetIntVec($33, OldInt33);
  372.   if OldInt33<>Nil then
  373.     SetIntVec($33, @NewInt33);
  374.  
  375.   SaveExit:=ExitProc;
  376.   ExitProc:=@ExitMouse;
  377. end.
  378.